#include "conf_read.h"

#include <map>
#include <stdio.h>
//程序需要的本地头文件
#include "pfunc.h"
#include "Log.h"
#include "lib_acl.h"
#include "acl_cpp/lib_acl.hpp"
#include "pfunc_print.h"

//get node attr
static void getAtt(const acl::xml_node* node,std::map<std::string,std::string> &atts_)
{
	const acl::xml_attr* attr = node->first_attr();
	while (attr)
	{
		std::map<std::string,std::string>::iterator it = atts_.find(std::string(attr->get_name()));
		if(it != atts_.end())
		{
			it->second = std::string(attr->get_value());
		}
		attr = node->next_attr();
	}
};

void pyfree::readAppConf(GatherConf &conf, std::string xml_)
{
	try
	{
		acl::string buf;
		if (acl::ifstream::load(xml_.c_str(), &buf) == false)
		{
			Print_WARN("load %s error %s\r\n", xml_.c_str(), acl::last_serror());
			return;
		}

		acl::xml1 xml;
		xml.update(buf);

		acl::xml_node* node 	= &(xml.get_root());
		acl::xml_node* child 	= node->first_child();
		while (child)
		{
			if(0==strcmp(child->tag_name(), "appconf"))
			{
				node	= child;
				child 	= node->first_child();
				while (child)
				{
					//
					if (0==strcmp("DiskSymbol",child->tag_name())) 
					{
						const char* val_ = child->text();
						if (1 == strlen(val_))
							conf.diskSymbol = val_[0];
					}
					//
					if (0==strcmp("FreeSizeLimit",child->tag_name())) 
					{
						const char* val_ = child->text();
						if (strlen(val_)>0)
							conf.freeSizeLimit = atoi(val_);
						if (conf.freeSizeLimit < 1000)
							conf.freeSizeLimit = 1000;
					}
					//
					if (0==strcmp("GLogDir" , child->tag_name())) 
					{		
						const char* val_ = child->text();
						if(strlen(val_)>0)			
							conf.gLogDir = std::string(val_);
					}
					//
					if (0==strcmp("GatherPath" , child->tag_name())) 
					{
						const char* val_ = child->text();
						if(strlen(val_)>0)			
							conf.gatherPath = std::string(val_);
					}
					if (0==strcmp("GmapPath" , child->tag_name())) 
					{
						const char* val_ = child->text();
						if(strlen(val_)>0)			
							conf.gmapPath = std::string(val_);
					}
					child = node->next_child();
				}
				Print_NOTICE("\nDiskSymbol=%c\nFreeSizeLimit=%d\nGLogDir=%s\nGatherPath=%s\nGmapPath=%s\r\n"
					,conf.diskSymbol
					,conf.freeSizeLimit
					,conf.gLogDir.c_str()
					,conf.gatherPath.c_str()
					,conf.gmapPath.c_str());
				break;
			}
			child = node->next_child();
		}
		// Print_NOTICE("success for read %s!\n",xml_.c_str());
		CLogger::createInstance()->Log(MsgInfo,"success for read %s!\n",xml_.c_str());
	}
	catch (...)
	{
		Print_WARN("error for read %s!\n",xml_.c_str());
	}
}
//转发接口
void init_tran_atts(std::map<std::string, std::string> &atts_)
{
	atts_["id"] 			= "";
	atts_["channeltype"] 	= "";
	atts_["channelid"] 		= "";
	atts_["protocolid"] 	= "";
	atts_["name"] 			= "";
	atts_["desc"] 			= "";
};

void read_tran_atts(pyfree::Transmit &tran_, std::map<std::string, std::string> atts_)
{
	tran_.id 			= atoi(atts_["id"].c_str());
	tran_.channeltype 	= atoi(atts_["channeltype"].c_str());
	tran_.channelid 	= atoi(atts_["channelid"].c_str());
	tran_.protocolid 	= atoi(atts_["protocolid"].c_str());
	tran_.name			= atts_["name"];
	tran_.desc			= atts_["desc"];
};

//串口参数
void init_sp_atts(std::map<std::string, std::string> &atts_)
{
	atts_["id"] = "";
	atts_["name"] = "";
	atts_["BaudRate"] = "";
	atts_["DataBit"] = "";
	atts_["Parity"] = "";
	atts_["StopBit"] = "";
	atts_["ReadCount"] = "";
	atts_["ReadSleep"] = "";
	atts_["ComModel"] = "";
};

void read_sp_atts(pyfree::SerialPort &sp_,std::map<std::string, std::string> atts_)
{
	sp_.id = atoi(atts_["id"].c_str());
	sp_.name = atts_["name"];
	// sp_.name = UTF_82ASCII(atts_["name"]);
	sp_.BaudRate = atoi(atts_["BaudRate"].c_str());
	sp_.DataBit = atoi(atts_["DataBit"].c_str());
	sp_.Parity = atts_["Parity"];
	sp_.StopBit = atoi(atts_["StopBit"].c_str());
	sp_.readCount = 2;
	if (!atts_["ReadCount"].empty())
	{
		sp_.readCount = atoi(atts_["ReadCount"].c_str());
		if (sp_.readCount < 1)
		{
			sp_.readCount = 1;
		}
	}
	sp_.readSleep = 100;
	if (!atts_["ReadSleep"].empty())
	{
		sp_.readSleep = atoi(atts_["ReadSleep"].c_str());
		if (sp_.readSleep < 10) 
		{
			sp_.readSleep = 10;
		}
	}
	sp_.com_model = 1;
	if (!atts_["ComModel"].empty())
	{
		sp_.com_model = atoi(atts_["ComModel"].c_str());
	}
};
//网口参数
void init_net_atts(std::map<std::string, std::string> &atts)
{
	atts["id"] 			= "";
	atts["type"] 		= "";
	atts["ptype"] 		= "";
	atts["name"] 		= "";
	atts["ip"] 			= "";
	atts["port"] 		= "";
	atts["readheart"] 	= "";
};

void read_net_atts(pyfree::NetPort &net_,std::map<std::string, std::string> atts_,std::string xml_)
{
	net_.id = atoi(atts_["id"].c_str());
	net_.type = atoi(atts_["type"].c_str());
	net_.ptype = atoi(atts_["ptype"].c_str());
	// net_.name = UTF_82ASCII(atts_["name"]);
	net_.name = atts_["name"];
	if(!atts_["ip"].empty())
	{
		net_.ip = atts_["ip"];
	}else{
		net_.ip = atts_["127.0.0.1"];
	}
	// net_.ip = atts_["ip"];
	if(!atts_["port"].empty())
	{
		net_.port = atoi(atts_["port"].c_str());
	}else{
		net_.port = 60000;
	}
	// net_.port = atoi(atts_["port"].c_str());
	if (!net_.ip.empty()&&"*"!= net_.ip &&!pyfree::ipCheck(net_.ip))
	{
		Print_WARN("read xml file[%s] error,please check nettype(%d) ip(%s): [%s %s %d]!"
			, xml_.c_str(), net_.id, net_.ip.c_str()
			, __FILE__, __FUNCTION__, __LINE__);
	}
	net_.readHeartTime = false;
	if (!atts_["readheart"].empty())
	{
		net_.readHeartTime = atoi(atts_["readheart"].c_str()) > 0 ? true : false;
	}
};
//协议参数
void init_proto_atts(std::map<std::string, std::string> &atts_)
{
	atts_["id"] 			= "";
	atts_["file"] 			= "";
	atts_["downcmd"] 		= "";
	atts_["upcmd"] 			= "";
	atts_["totalcallsleep"] = "";
	atts_["oldState"] 		= "";
	atts_["ykSetVal"] 		= "";
	atts_["retValNull"] 	= "";
};

void read_proto_atts(pyfree::ProtocolDef &proto_,std::map<std::string, std::string> atts_)
{
	proto_.id = atoi(atts_["id"].c_str());
	proto_.luafile = atts_["file"];
	proto_.downType = atoi(atts_["downcmd"].c_str());
	proto_.upType = atoi(atts_["upcmd"].c_str());
	proto_.totalcallsleep = 100;
	if (!atts_["totalcallsleep"].empty())
	{
		proto_.totalcallsleep = atoi(atts_["totalcallsleep"].c_str());
	}
	proto_.oldState = 0;
	if (!atts_["oldState"].empty())
	{
		proto_.oldState = atoi(atts_["oldState"].c_str());
	}
	proto_.ykSetVal = 0;
	if (!atts_["ykSetVal"].empty())
	{
		proto_.ykSetVal = atoi(atts_["ykSetVal"].c_str());
	}
	proto_.retValNull = 0;
	if (!atts_["retValNull"].empty())
	{
		proto_.retValNull = atoi(atts_["retValNull"].c_str());
	}
};
//采集接口
void init_gather_atts(std::map<std::string, std::string> &atts_)
{
	atts_["id"] = "";
	atts_["channeltype"] = "";
	atts_["channelid"] = "";
	atts_["name"] = "";
	atts_["protocolid"] = "";
	atts_["hexflag"] = "";
	atts_["controlsleep"] = "";
	atts_["TimePush"] = "";
	atts_["linkInitKey"] = "";
};

void read_gather_atts(pyfree::Gather &gather_,std::map<std::string, std::string> &atts_)
{
	gather_.atts.controlSleep 	= 50;
	gather_.atts.id 			= atoi(atts_["id"].c_str());
	gather_.atts.channeltype 	= atoi(atts_["channeltype"].c_str());
	gather_.atts.channelid 		= atoi(atts_["channelid"].c_str());
	gather_.atts.protocolid 	= atoi(atts_["protocolid"].c_str());
	// gather_.atts.name 		= UTF_82ASCII(atts_["name"]);
	gather_.atts.name 			= atts_["name"];
	gather_.atts.hexflag 		= (atoi(atts_["hexflag"].c_str()) > 0 ? true : false);
	if (!atts_["controlsleep"].empty()) 
	{
		gather_.atts.controlSleep = atoi(atts_["controlsleep"].c_str());
	}
	gather_.atts.timePush = 10;
	if (!atts_["TimePush"].empty())
	{
		gather_.atts.timePush = atoi(atts_["TimePush"].c_str());
		if (gather_.atts.timePush < 2)
		{
			gather_.atts.timePush = 2;
		}
	}
	gather_.atts.linkInitKey = false;
	if (!atts_["linkInitKey"].empty())
	{
		gather_.atts.timePush = atoi(atts_["linkInitKey"].c_str())>0?true:false;
	}
};
//采集点
void init_p_atts(std::map<std::string, std::string> &atts_)
{
	atts_["id"] 		= "";
	atts_["type"] 		= "";
	atts_["addr"] 		= "";
	atts_["devaddr"] 	= "";
	atts_["ip"] 		= "";
	atts_["logflag"] 	= "";
	atts_["upinterval"] = "";
	atts_["defvalue"] 	= "";
};

void read_p_atts(pyfree::PInfo &pinfo_,std::map<std::string, std::string> atts_)
{
	pinfo_.value = 0.0;
	pinfo_.ipStr = "127.0.0.1";
	pinfo_.id = atoi(atts_["id"].c_str());
	pinfo_.type = (pyfree::PType)atoi(atts_["type"].c_str());
	pinfo_.addr = atoi(atts_["addr"].c_str());
	pinfo_.dev_addr = 1;	//设置为1
	if (!atts_["ip"].empty()) 
	{
		pinfo_.ipStr = atts_["ip"];
	}
	if (!atts_["devaddr"].empty()) 
	{
		pinfo_.dev_addr = atol(atts_["devaddr"].c_str());	//如果指定设备地址,直接采用
	}
	if (!atts_["ip"].empty()&&atts_["devaddr"].empty()) 
	{
		//
		pinfo_.dev_addr = pyfree::ipToInt(pinfo_.ipStr);	//如果设置了ip,采用ip转换,主要是级联下级采集服务用到
	}
	//
	pinfo_.logFlag = true;
	if (!atts_["logflag"].empty()) 
	{
		pinfo_.logFlag = atoi(atts_["logflag"].c_str()) > 0 ? true : false;
	}
	//
	pinfo_.upInterval = 1;
	if (!atts_["upinterval"].empty()) 
	{
		pinfo_.upInterval = atoi(atts_["upinterval"].c_str());
		if (pinfo_.upInterval < 1)
			pinfo_.upInterval = 1;
	}
	pinfo_.defvalue = 0.0;
	if (!atts_["defvalue"].empty()) 
	{
		pinfo_.defvalue = static_cast<float>(atof(atts_["defvalue"].c_str()));
		pinfo_.value = pinfo_.defvalue;
	}	
};
//计算点
void init_pf_atts(std::map<std::string, std::string> &atts_)
{
	atts_["id"] = "";
	atts_["type"] = "";
	atts_["expr"] = "";
};

void read_pf_atts(pyfree::PFuncInfo &pfinfo_,std::map<std::string, std::string> atts_)
{
	pfinfo_.value = 0.0;
	pfinfo_.id = atoi(atts_["id"].c_str());
	pfinfo_.type = (pyfree::PType)atoi(atts_["type"].c_str());
	pfinfo_.addr = -1;
	pfinfo_.expr = atts_["expr"];
};
//计算公式参数
void init_arg_atts(std::map<std::string, std::string> &atts_)
{
	atts_["name"] = "";
	atts_["paddr"] = "";
};

void read_arg_atts(pyfree::PFuncArg &farg_,std::map<std::string, std::string> atts_)
{
	farg_.name = atts_["name"];
	farg_.paddr = atoi(atts_["paddr"].c_str());
};
//配置信息
void pyfree::readGathers(ComManagerDef &commdef, std::string xml_)
{
	try
	{
		acl::string buf;
		if (acl::ifstream::load(xml_.c_str(), &buf) == false)
		{
			Print_WARN("load %s error %s\r\n", xml_.c_str(), acl::last_serror());
			return;
		}

		acl::xml1 xml;
		xml.update(buf);

		acl::xml_node* node 	= &(xml.get_root());
		acl::xml_node* child 	= node->first_child();
		while (child)
		{
			if(0==strcmp(child->tag_name(), "ComM"))
			{
				node	= child;
				child 	= node->first_child();
				while (child)
				{
					//
					if (0==strcmp("transmit",child->tag_name())) 
					{
						std::map<std::string, std::string> atts_;
						init_tran_atts(atts_);
						getAtt(child,atts_);
						pyfree::Transmit tran_;
						read_tran_atts(tran_,atts_);
						Print_NOTICE("\ntransmit:\nid=%d\nchanneltype=%d\nchannelid=%d\nprotocolid=%d\r\n",
							tran_.id,tran_.channeltype,tran_.channelid,tran_.protocolid);
						commdef.trans[tran_.id]=tran_;
					}
					//
					if (0==strcmp("serialport",child->tag_name())) 
					{
						std::map<std::string, std::string> atts_;
						init_sp_atts(atts_);
						getAtt(child,atts_);
						pyfree::SerialPort sp_;
						read_sp_atts(sp_, atts_);
						Print_NOTICE("\nSerialPort:\nid=%d\nname=%s\nBaudRate=%d\nDataBit=%d\nParity=%s\nStopBit=%d\nreadCount=%d\nreadSleep=%d\r\n",
							sp_.id
							,sp_.name.c_str()
							,sp_.BaudRate
							,sp_.DataBit
							,sp_.Parity.c_str()
							,sp_.StopBit
							,sp_.readCount
							,sp_.readSleep);
						commdef.spdefs[sp_.id] = sp_;
					}
					//
					if (0==strcmp("netport" , child->tag_name())) 
					{		
						std::map<std::string, std::string> atts_;
						init_net_atts(atts_);
						getAtt(child,atts_);
						pyfree::NetPort net_;
						read_net_atts(net_, atts_, xml_);
						Print_NOTICE("\nnetport:\nid=%d\nname=%s\ntype=%d\nptype=%d\nip=%s\nport=%d\nreadHeartTime=%d\r\n",
							net_.id
							,net_.name.c_str()
							,net_.type
							,net_.ptype
							,net_.ip.c_str()
							,net_.port
							,net_.readHeartTime);
						commdef.netdefs[net_.id] = net_;
					}
					//
					if (0==strcmp("protocol" , child->tag_name())) 
					{
						std::map<std::string, std::string> atts_;
						init_proto_atts(atts_);
						getAtt(child,atts_);
						pyfree::ProtocolDef proto_;
						read_proto_atts(proto_, atts_);
						Print_NOTICE("\nProtocolDef:\nid=%d\nluafile=%s\ndownType=%d\nupType=%d\ntotalcallsleep=%d"
							"\noldState=%d\nykSetVal=%d\nretValNull=%d\r\n",
							proto_.id
							,proto_.luafile.c_str()
							,proto_.downType
							,proto_.upType
							,proto_.totalcallsleep
							,proto_.oldState
							,proto_.ykSetVal
							,proto_.retValNull);
						commdef.protodefs[proto_.id] = proto_;
					}
					if (0==strcmp("gather" , child->tag_name())) 
					{
						std::map<std::string, std::string> atts_;
						init_gather_atts(atts_);
						getAtt(child,atts_);
						pyfree::Gather gather_;
						read_gather_atts(gather_, atts_);
						Print_NOTICE("\nGatherAtts:\nid=%d\nnmae=%s\ndesc=%s\nchanneltype=%d\nchannelid=%d"
							"\nprotocolid=%d\nhexflag=%d\ncontrolSleep=%d\ntimePush=%d\nlinkInitKey=%d\r\n",
							gather_.atts.id
							,gather_.atts.name.c_str()
							,gather_.atts.desc.c_str()
							,gather_.atts.channeltype
							,gather_.atts.channelid
							,gather_.atts.protocolid
							,gather_.atts.hexflag
							,gather_.atts.controlSleep
							,gather_.atts.timePush
							,gather_.atts.linkInitKey);

							acl::xml_node* pnode 	= child;
							acl::xml_node* pchild 	= pnode->first_child();
							while (pchild){
								if (0==strcmp("pinfo" , pchild->tag_name()))
								{
									atts_.clear();
									init_p_atts(atts_);
									getAtt(pchild,atts_);
									pyfree::PInfo pinfo_;
									read_p_atts(pinfo_, atts_);
									Print_NOTICE("\npinfo:\nid=%d\ntype=%d\naddr=%d\nvalue=%f\ndefvalue=%f"
										"\nipstr=%s\niplong=%lu\nupdatetime=%u\nsendtime=%u\nupInterval=%d\nlogFlag=%d\r\n",
										pinfo_.id
										,pinfo_.type
										,pinfo_.addr
										,pinfo_.value
										,pinfo_.defvalue
										,pinfo_.ipStr.c_str()
										,pinfo_.dev_addr
										,pinfo_.updateTime
										,pinfo_.sendTime
										,pinfo_.upInterval
										,pinfo_.logFlag?1:0);
									gather_.pinfos.push_back(pinfo_);
								}
								if (0==strcmp("pfinfo" , pchild->tag_name()))
								{
									atts_.clear();
									init_pf_atts(atts_);
									getAtt(pchild,atts_);
									pyfree::PFuncInfo pfinfo_;
									read_pf_atts(pfinfo_, atts_);
									Print_NOTICE("\npfinfo:\nid=%d\ntype=%d\naddr=%d\nvalue=%f\ndefvalue=%f"
										"\nipstr=%s\niplong=%lu\nupdatetime=%u\nsendtime=%u\nupInterval=%d\nlogFlag=%d\r\n",
										pfinfo_.id
										,pfinfo_.type
										,pfinfo_.addr
										,pfinfo_.value
										,pfinfo_.defvalue
										,pfinfo_.ipStr.c_str()
										,pfinfo_.dev_addr
										,pfinfo_.updateTime
										,pfinfo_.sendTime
										,pfinfo_.upInterval
										,pfinfo_.logFlag?1:0);
									acl::xml_node* argnode 	= pchild;
									acl::xml_node* argchild = argnode->first_child();
									while (argchild){
										if (0==strcmp("arg" , argchild->tag_name()))
										{
											atts_.clear();
											init_arg_atts(atts_);
											getAtt(argchild, atts_);
											PFuncArg pfarg_;
											read_arg_atts(pfarg_, atts_);
											Print_NOTICE("\nPFuncArg:\nname=%s\npaddr=%d\r\n",
												pfarg_.name.c_str()
												,pfarg_.paddr);
											pfinfo_.args.push_back(pfarg_);
										}
										argchild = argnode->next_child();
									}
									gather_.pfuncinfos.push_back(pfinfo_);
								}

								pchild = pnode->next_child();
							}
						commdef.gathers[gather_.atts.id] = gather_;
					}
					child = node->next_child();
				}
				break;
			}
			child = node->next_child();
		}
		Print_NOTICE("success for read %s!\n",xml_.c_str());
	}
	catch (...)
	{
		Print_WARN("error for read %s!\n",xml_.c_str());
	}
};
//
//信道点映射
void init_from_atts(std::map<std::string, std::string> &atts_)
{
	atts_["gid"] 	= "";
	atts_["pid"] 	= "";
	atts_["ptype"] 	= "";
};

void read_from_atts(pyfree::PFrom &pfrom_,std::map<std::string, std::string> atts_)
{
	pfrom_.gid = atoi(atts_["gid"].c_str());
	pfrom_.pid = atoi(atts_["pid"].c_str());
	pfrom_.ptype = (pyfree::PType)atoi(atts_["ptype"].c_str());
};
//转发点映射
void init_to_atts(std::map<std::string, std::string> &atts_)
{
	atts_["pid"] = "";
	atts_["ptype"] = "";
};

void read_to_atts(pyfree::PTo &pto_,std::map<std::string, std::string> atts_)
{
	pto_.pid = atoi(atts_["pid"].c_str());
	pto_.ptype = (pyfree::PType)atoi(atts_["ptype"].c_str());
	pto_.value = 0.0;
};
//映射配置信息
void pyfree::readPMaps(std::list<PMap> &pmaps, std::string xml_)
{
	try
	{
		acl::string buf;
		if (acl::ifstream::load(xml_.c_str(), &buf) == false)
		{
			Print_WARN("load %s error %s\r\n", xml_.c_str(), acl::last_serror());
			return;
		}

		acl::xml1 xml;
		xml.update(buf);

		acl::xml_node* node 	= &(xml.get_root());
		acl::xml_node* child 	= node->first_child();
		while (child)
		{
			if(0==strcmp(child->tag_name(), "maps"))
			{
				acl::xml_node* mnode	= child;
				acl::xml_node* mchild 	= mnode->first_child();
				while (mchild)
				{
					if(0==strcmp(mchild->tag_name(), "map"))
					{
						acl::xml_node* pnode 	= mchild;
						acl::xml_node* pchild 	= pnode->first_child();
						pyfree::PMap pmap_;
						while (pchild)
						{
							if(0==strcmp(pchild->tag_name(), "from"))
							{
								std::map<std::string, std::string> atts_;
								init_from_atts(atts_);
								getAtt(pchild,atts_);
								read_from_atts(pmap_.pfrom, atts_);
								Print_NOTICE("\nPFrom:\ngid=%d\npid=%d\nptype=%d\r\n"
									,pmap_.pfrom.gid
									,pmap_.pfrom.pid
									,pmap_.pfrom.ptype);
							}
							if(0==strcmp(pchild->tag_name(), "to"))
							{
								std::map<std::string, std::string> atts_;
								init_to_atts(atts_);
								getAtt(pchild,atts_);
								read_to_atts(pmap_.pto, atts_);
								Print_NOTICE("\nPTo:\npid=%d\nptype=%d\r\n"
									,pmap_.pto.pid
									,pmap_.pto.ptype);
							}
							pchild = pnode->next_child();
						}
						pmaps.push_back(pmap_);
					}
					mchild = mnode->next_child();
				}
			}
			child = node->next_child();
		}
		Print_NOTICE("success for read %s!\n",xml_.c_str());
	}
	catch (...)
	{
		Print_WARN("error for read %s!\n",xml_.c_str());
	}
};
